<?php
require_once 'mods/class_database.php';
require_once 'mods/log.php';
require_once 'mods/postgresql_exception.php';
class postgresql extends database
{
    public static $keyWords=array('order', 'user');

    protected $_logger;

    protected $_throwException = false;

    public function setExceptionEnabled($enabled = true)
    {
        $this->_throwException=(boolean) $enabled;
    }

    private function __construct($dsn=null)
    {
        if($dsn==null)$dsn='dbname=atm1 user=root password=286aesLM';
        $this->conn=$this->connect($dsn);
        $this->_logger=&Log::factory('file','dbnew_error.log');
        register_shutdown_function(array(&$this, '__destruct'));
    }

    public function __destruct()
    {
        $this->close();
        $this->_logger->close();
    }

    static public function instance($dsn=null)
    {
        static $obj;
        if(!isset($obj))
        {
            $obj=new postgresql($dsn);
        }
        return $obj;
    }

    public function connect($dsn)
    {
        return @pg_connect($dsn);
    }

    public function close()
    {
        if(is_resource($this->conn))
        {
            return @pg_close($this->conn);
        }
    }

    public function escapeString($string)
    {
        $t=pg_escape_string($string);
        return $t;
    }

    public function quoteString($string)
    {
        $t=$this->escapeString($string);
        return "'{$t}'";
    }

    public function select($sql, $assoc=true)
    {
$arReturn=array();
if ($sql){
        $result=@pg_query($this->conn,$sql);
        if (@pg_last_error($this->conn))
        {
            $this->_logger->log(date('Y-m-d H:i:s').' '.pg_last_error($this->conn));
            $this->_logger->log(date('Y-m-d H:i:s').' '.$sql);
            if ($this->_throwException)
            {
                throw new PostgresqlException(pg_last_error($this->conn));
            }
            return false;
        }
        $arReturn=array();
        if($assoc)
        {
            while($row=pg_fetch_assoc($result))
            {
                $arReturn[]=$row;
            }
        }
        else
        {
            while($row=pg_fetch_row($result))
            {
                $arReturn[]=$row;
            }
        }
}
        return $arReturn;
    }

    public function getOne($sql)
    {
        $sql=$sql.' LIMIT 1';
        $result=@pg_query($this->conn,$sql);
        if (@pg_last_error($this->conn))
        {
            $this->_logger->log(date('Y-m-d H:i:s').' '.pg_last_error($this->conn));
            $this->_logger->log(date('Y-m-d H:i:s').' '.$sql);
            if ($this->_throwException)
            {
                throw new PostgresqlException(pg_last_error($this->conn));
            }
            return false;
        }
        if(pg_num_rows($result))
        $value=pg_fetch_result($result,0,0);
        return $value;
    }

    public function insert($tableName, $arValues)
    {
        $id=null;
        $arFieldList=array();
        $arValueList=array();
        foreach($arValues as $key=>$value)
        {
            if (false !== array_search($key, self::$keyWords)) {
                $arFieldList[]='"' . $key . '"';
            }
            else {
                $arFieldList[]=$key;
            }
            if(strtolower($value)=='#id#')
            {
                $value=$id=$this->nextId($tableName,$key);
            }
            $arValueList[]=$this->quoteSmart($value);
        }
        $sFieldList=implode(',',$arFieldList);
        $sValueList=implode(',',$arValueList);

        $sql="INSERT INTO $tableName ($sFieldList) VALUES($sValueList)";
//echo $sql,'<br>';
        $result=@pg_query($sql);
        if (@pg_last_error($this->conn))
        {
            $this->_logger->log(date('Y-m-d H:i:s').' '.pg_last_error($this->conn));
            $this->_logger->log(date('Y-m-d H:i:s').' '.$sql);
            if ($this->_throwException)
            {
                throw new PostgresqlException(pg_last_error($this->conn));
            }
            return false;
        }
        return $id;
    }

public function update($tableName,$arUpdate,$sWhere=null)
    {
        if(!empty($sWhere))
        {
            $arSet=array();
            foreach($arUpdate as $key=>$value)
            {
                if (false !== array_search($key, self::$keyWords))
                {
                    $key='"' . $key . '"';
                }
                $arSet[]=$key . '=' . $this->quoteSmart($value);
            }
            $sSet=implode(',', $arSet);

            $sql="UPDATE $tableName SET $sSet";
            if($sWhere) $sql.=" WHERE $sWhere";
//echo $sql,'<br>';
            $result=@pg_query($sql);

            if (@pg_last_error($this->conn))
            {
                $this->_logger->log(date('Y-m-d H:i:s').' '.pg_last_error($this->conn));
                $this->_logger->log(date('Y-m-d H:i:s').' '.$sql);
                if ($this->_throwException)
                {
                    throw new PostgresqlException(pg_last_error($this->conn));
                }
                return false;
            }
            return pg_affected_rows($result);
        }
    }

    public function delete($tableName,$sWhere=null)
    {
        if($sWhere)
        {
            $sql="DELETE FROM $tableName WHERE $sWhere";
//echo $sql,'<br>';
            $result=@pg_query($sql);
            if (@pg_last_error($this->conn))
            {
                $this->_logger->log(date('Y-m-d H:i:s').' '.pg_last_error($this->conn));
                $this->_logger->log(date('Y-m-d H:i:s').' '.$sql);
                if ($this->_throwException)
                {
                    throw new PostgresqlException(pg_last_error($this->conn));
                }
                return false;
            }
            return pg_affected_rows($result);
        }
    }

    public function nextId($tableName, $sColumn)
    {
        $result=$this->select("SELECT max($sColumn) FROM $tableName");
        $id=$result[0]['max'];
        $id++;
        return $id;
    }

    public function begin()
    {
        $sql="BEGIN WORK";
        $result=pg_query($this->conn, $sql);
        if (@pg_last_error($this->conn))
        {
            $this->_logger->log(date('Y-m-d H:i:s').' '.pg_last_error($this->conn));
            $this->_logger->log(date('Y-m-d H:i:s').' '.$sql);
            return false;
        }
        return true;
    }

    public function commit()
    {
        $sql="COMMIT";
        $result=pg_query($this->conn, $sql);
        if (@pg_last_error($this->conn))
        {
            $this->_logger->log(date('Y-m-d H:i:s').' '.pg_last_error($this->conn));
            $this->_logger->log(date('Y-m-d H:i:s').' '.$sql);
            return false;
        }
        return true;
    }

    public function rollback()
    {
        $sql="ROLLBACK";
        $result=pg_query($this->conn, $sql);
        if (@pg_last_error($this->conn))
        {
            $this->_logger->log(date('Y-m-d H:i:s').' '.pg_last_error($this->conn));
            $this->_logger->log(date('Y-m-d H:i:s').' '.$sql);
            return false;
        }
        return true;
    }

    public function beginTransaction()
    {
        $sql="BEGIN";
        $result=pg_query($this->conn, $sql);
        if (@pg_last_error($this->conn))
        {
            $this->_logger->log(date('Y-m-d H:i:s').' '.pg_last_error($this->conn));
            $this->_logger->log(date('Y-m-d H:i:s').' '.$sql);
            return false;
        }
        return true;
    }

    public function query($sql)
    {
        $return=false;
        if (!empty($sql))
        {
            $result=@pg_query($this->conn, $sql);
            if (@pg_last_error($this->conn))
            {
                $this->_logger->log(date('Y-m-d H:i:s').' '.pg_last_error($this->conn));
                $this->_logger->log(date('Y-m-d H:i:s').' '.$sql);
                if ($this->_throwException)
                {
                    throw new PostgresqlException(pg_last_error($this->conn));
                }
            }
            else
            {
                $return=true;
            }
        }
        return $return;
    }

    public function executeFunction($sql)
    {
        $result=@pg_query($this->conn,$sql);
        if (@pg_last_error($this->conn))
        {
            $this->_logger->log(date('Y-m-d H:i:s').' '.pg_last_error($this->conn));
            $this->_logger->log(date('Y-m-d H:i:s').' '.$sql);
            if ($this->_throwException)
            {
                throw new PostgresqlException(pg_last_error($this->conn));
            }
            return false;
        }
        if(pg_num_rows($result))
        $value=pg_fetch_result($result,0,0);
        return $value;
    }
}
?>